package com.tencent.elife.view;

import com.tencent.elife.utils.L;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;

/**
 * @author zijianlu
 * @version 创建时间：2012-5-4 弹性的listView
 */

public class BouncyListView extends ListView implements Runnable {
    private float mLastDownY = 0f;
    private int mDistance = 0;
    private int mStep = 10;
    private boolean mPositive = false;

    public BouncyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BouncyListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public BouncyListView(Context context) {
        super(context);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (mLastDownY == 0f && mDistance == 0) {
                mLastDownY = event.getY();
                L.D("list", "---dispatchTouchEvent:--" + event.getAction());
            }
            break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        L.D("list", "onTouchEvent:" + event.getAction());

        switch (event.getAction()) {
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            if (mDistance != 0) {
                mStep = 1;
                mPositive = mDistance >= 0;
                this.post(this);
                break;
            }

            mLastDownY = 0f;
            mDistance = 0;
            break;

        case MotionEvent.ACTION_MOVE:
            if (mLastDownY != 0f) {
                mDistance = (int) (mLastDownY - event.getY());
                L.D("list", "onTouchEvent: move lastDownY: " + mLastDownY
                    + " dis:" + mDistance);
                if ((mDistance < 0 && getFirstVisiblePosition() == 0 && getChildAt(
                    0).getTop() == 0)) {

                    L.D("list", "onTouchEvent: move scrollTo:" + mDistance);
                    mDistance /= 3;
                    scrollTo(0, mDistance);

                    event.setAction(MotionEvent.ACTION_CANCEL);
                    // setSelection(0);
                    break;
                } else if (mDistance > 0
                    && getLastVisiblePosition() == getCount() - 1) {
                    mDistance /= 3;
                    scrollTo(0, mDistance);

                    event.setAction(MotionEvent.ACTION_CANCEL);
                    // setSelection(getCount() - 1);
                    break;
                }
            }

            L.D("list", "-------onTouchEvent: move -----");

            mDistance = 0;
            break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void run() {
        // 手指松开后，回到原来的位置
        mDistance += mDistance > 0 ? -mStep : mStep;
        scrollTo(0, mDistance);
        if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) {
            scrollTo(0, 0);
            mDistance = 0;
            mLastDownY = 0f;
            return;
        }
        mStep += 10;
        this.postDelayed(this, 10);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        int lastPos = getCount() - 1;
        if (lastPos >= 0) {
            setSelection(lastPos);
        }

    }

}